package com.xingfudazi.common.core.domain;

import com.xingfudazi.common.constant.HttpStatus;
import lombok.Data;
import lombok.experimental.Accessors;
import org.slf4j.MDC;

import java.util.HashMap;
import java.util.Map;

/**
 * 工共返回值
 *
 * @param <T>
 * @author ming
 */
@Data
@Accessors(chain = true)
public class Result<T> {

    /**
     * 状态码
     */
    private int code;

    /**
     * 消息返回信息
     */
    private String message;

    /**
     * 返回值
     */
    private T data;

    private Boolean success;

    private String traceId;

    /**
     * 成功状态码 200
     */
    private final static int SUCCESS_CODE = HttpStatus.SUCCESS;

    /**
     * 失败状态码 501
     */
    private final static int FAIL_CODE = HttpStatus.ERROR;

    /**
     * 成功默认消息返回体
     */
    private final static String SUCCESS_MESSAGE = "success";

    /**
     * 失败，默认消息返回体
     */
    private final static String FAIL_MESSAGE = "fail";


    /**
     * 成功默认消息
     */
    public static <T> Result<T> success() {
        return new Result<>(SUCCESS_CODE, true, SUCCESS_MESSAGE);
    }

    /**
     * 失败默认消息
     */
    public static <T> Result<T> fail() {
        return new Result<>(FAIL_CODE, false, FAIL_MESSAGE);
    }


    public static <T> Result<T> fail(String message) {
        return new Result<>(FAIL_CODE, false, message);
    }


    /**
     * 成功默认消息 (无任何数据类型状态下，默认返回map)
     */
    public static Result<Map<String, Object>> successMap() {
        return new Result<>(SUCCESS_CODE, true, SUCCESS_MESSAGE, new HashMap<>(16));
    }

    /**
     * 失败默认消息
     */
    public static Result<Map<String, Object>> failMap() {
        return new Result<>(FAIL_CODE, false, FAIL_MESSAGE, new HashMap<>(16));
    }

    /**
     * 成功自定义t
     *
     * @param data 数据
     */
    public static <T> Result<T> success(T data) {
        return new Result<T>(SUCCESS_CODE, true, SUCCESS_MESSAGE, data);
    }

    /**
     * 失败自定义t
     *
     * @param data 数据
     */
    public static <T> Result<T> fail(T data) {
        return new Result<>(FAIL_CODE, false, FAIL_MESSAGE, data);
    }


    /**
     * 成功自定义 message 和 t
     *
     * @param message 消息
     * @param data    数据
     */
    public static <T> Result<T> success(String message, T data) {
        return new Result<>(SUCCESS_CODE, true, SUCCESS_MESSAGE, data);
    }


    /**
     * 失败自定义 message 和 t
     *
     * @param message 消息
     * @param data    数据
     */
    public static <T> Result<T> fail(String message, T data) {
        return new Result<>(FAIL_CODE, false, message, data);
    }


    /**
     * key value 形式存储map添加
     */
    public Result<Map<String, Object>> add(String key, Object value) {
        Map<String, Object> mapI = null;
        // 将结果进行map转换
        try {
            mapI = (Map<String, Object>) this.getData();
            if (mapI == null) {
                mapI = new HashMap<>(16);
            }
        } catch (Exception e) {
            // 如果转换失败则重新new 一个
            mapI = new HashMap<>(16);
        }
        mapI.put(key, value);
        return Result.success(mapI);
    }

    private Result(){
        this.traceId = MDC.get("TRACE_ID");
    }

    private Result(int code, Boolean success, String message, T data) {
        this();
        this.code = code;
        this.message = message;
        this.data = data;
        this.success = success;
    }

    private Result(int code, Boolean success, String message) {
        this();
        this.code = code;
        this.message = message;
        this.success = success;
    }




    public Boolean isSuccess() {
        return success;
    }


    public String getTraceId() {
        return traceId;
    }

    public void setTraceId(String traceId) {
        this.traceId = traceId;
    }
}
